package com.lightsaber.trade.as.web.category;

import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.convention.annotation.Namespace;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springside.modules.orm.Page;
import org.springside.modules.utils.web.struts2.Struts2Utils;

import com.lightsaber.trade.as.entity.category.Category;
import com.lightsaber.trade.as.entity.category.CategoryNode;
import com.lightsaber.trade.as.entity.planning.Level1Planning;
import com.lightsaber.trade.as.entity.planning.Planning;
import com.lightsaber.trade.as.entity.planning.PlanningLevel;
import com.lightsaber.trade.as.entity.planning.PlanningStatus;
import com.lightsaber.trade.as.service.category.CategoryNodeService;
import com.lightsaber.trade.as.service.category.CategoryService;
import com.lightsaber.trade.as.service.planfirst.PlanFirstLevelManager;
import com.lightsaber.trade.as.service.planning.PlanningService;
import com.lightsaber.trade.core.common.util.CurrentUser;
import com.lightsaber.trade.core.web.BaseAction;

@Namespace("/category")
public class CategoryAction extends BaseAction {

    private static final long serialVersionUID = -6133932528005700711L;

    private static final Logger log = LoggerFactory.getLogger(CategoryAction.class);

    @Autowired
    private transient CategoryService categoryService;

    @Autowired
    private transient CategoryNodeService categoryNodeService;

    @Autowired
    private transient PlanFirstLevelManager planFirstLevelManager;

    @Autowired
    private transient PlanningService planningService;

    private Category category;// As same as ActionForm

    private CategoryNode root;

    private String xml;
    private String categoryId;

    // public CategoryNode node;
    // ****************** Page parameters *****************START
    private boolean search;

    @Value(value = "#{appProperties['category.page.size']}")
    private String pageSize;

    private Page<Category> page;
    private boolean isAdmin;
    private boolean related;

    private String level1PlanningId;

    private String canSelectMasterTree;
    private String deleteFromPage;

    // private

    // ****************** Page parameters *****************END

    @Override
    public String execute() {
        return list();
    }

    public String list() {
        try {
            if (search) {
                if (page == null) {
                    page = new Page<Category>(Integer.valueOf(pageSize));
                } else {
                    page.setPageSize(Integer.valueOf(pageSize));
                }

                if (!page.isOrderBySetted()) {
                    // page.setOrderBy(category.getPlanYear().toString());
                    // page.setOrderBy(category.getPlanningExerciseName());
                    // page.setOrderBy(category.getBranchName());
                    page.setOrder(Page.ASC);
                }

                String[] roles = CurrentUser.getRolesAsArrays();
                boolean isAdmin = false;
                if (canSelectMasterTree.equals("true")) {
                    isAdmin = true;
                }

                categoryService.findPage(category, page, roles, isAdmin);
            } else {
                category = null;// 点击clear按钮,清空页面
            }
//            ServletActionContext.getRequest().gets;

        } catch (Exception e) {
            log.error("error {}", e);
            addActionError(e.getMessage());
        }

        return SUCCESS;
    }

    public String save() {
        try {
            // categoryService.validateCategory(category);

            if (StringUtils.isBlank(category.getId())) {
                category.setIsArchivedImage(false);
                // category.setRoot(null);
                category.setOwnerNode(null);
                category.setEndorsementStatus(PlanningStatus.WaitingForSubmission);
                categoryService.createCategoryFromPage(category);

            } else {
                categoryService.saveCategory(category);
            }

            addActionMessage(getText(PROCESSED_SUCCESS));

        } catch (Exception e) {
            log.info("error {}", e.getMessage());
            addActionError(e.getMessage());
        }

        checkHasLevel1Planning();
        return INPUT;
    }

    public String saveAsNew() {
        try {
            Category categoryNew = categoryService.saveAsNew(category.getId(),
                    category.getBranchName());
            setCategory(categoryNew);
        } catch (Exception e) {
            addActionError(e.getMessage());
        }

        checkHasLevel1Planning();
        return INPUT;
    }

    public String saveAsNewWithPlanning() {
        log.debug("### saveAsNewWithPlanning... ");

        try {
            category = categoryService.saveAsNewWithPlanning(category.getId(),
                    category.getBranchName());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            addActionError(e.getMessage());
        }

        checkHasLevel1Planning();
        return INPUT;
    }

    private void checkHasLevel1Planning() {
        if (category != null && StringUtils.isNotBlank(category.getId())) {
            Level1Planning level1Planning = planFirstLevelManager
                    .findByBranchTree(category.getId());

            if (level1Planning != null) {
                level1PlanningId = level1Planning.getId();
            }
        }
    }

    public String getTreeGridData() {
        category = categoryService.findById(categoryId);
        StringBuffer body = new StringBuffer();

        generalXML(null, getCategoryId(), body, null);
        body.append("</I>");
        log.info("tree grid data : {}", body.toString());
        setXml(body.toString());

        return "tree-grid-file";
    }

    public void generalXML(final String parentId, final String categoryId, final StringBuffer body,
            final List<CategoryNode> children) {
        if (StringUtils.isBlank(parentId)) {
            CategoryNode root = categoryNodeService.findByCategoryId(categoryId);
            body.append("<I id='" + root.getId()
                    + "' A='&lt;a href=\"javascript:childOnClick(&apos;" + root.getId()
                    + "&apos;, &apos;root&apos; )\" &gt; " + root.getName() + " &lt;/a&gt;' >");
            // log.info("root : {}", body.toString());

             comparatorChildren(root.getChildren());
            generalXML(root.getId(), categoryId, body, root.getChildren());
        } else {
            if (!children.isEmpty()) {
                for (int i = 0; i < children.size(); i++) {
                    CategoryNode child = children.get(i);
                    if (child.getChildren().isEmpty()) {
                        body.append("<I id='" + child.getId()
                                + "'  A='&lt;a href=\"javascript:childOnClick(&apos;"
                                + child.getId() + "&apos;, &apos;" + child.getIsLeafNode()
                                + "&apos; )\" &gt; " + child.getName() + " &lt;/a&gt;' />");
                        // String a=
                        // "A='<a href=\"javascript:childOnClick(this, "+child.getIsLeafNode()+" )\">  "+child.getName()+" </a>'";
                        // String a =
                        // "A='&lt;a href=\"javascript:childOnClick(this, &apos; root&apos; )\" &gt; '"+child.getName()+"' &lt;/a&gt;'";
                    } else {
                        body.append("<I id='" + child.getId()
                                + "'  A='&lt;a href=\"javascript:childOnClick(&apos;"
                                + child.getId() + "&apos;, &apos;" + child.getIsLeafNode()
                                + "&apos; )\" &gt; " + child.getName() + " &lt;/a&gt;' >");
                         comparatorChildren(child.getChildren());
                        generalXML(child.getId(), categoryId, body, child.getChildren());
                        body.append("</I>");
                    }
                }
            }
        }
    }

    private void comparatorChildren(List<CategoryNode> list) {
        Collections.sort(list, new Comparator<CategoryNode>() {
            public int compare(CategoryNode node1, CategoryNode node2) {
                Calendar now = Calendar.getInstance();
                now.setTime(node1.getCreatedDate());
                long time1 = now.getTimeInMillis();
                now.setTime(node2.getCreatedDate());
                long time2 = now.getTimeInMillis();

                if (time1 > time2)
                    return 1;
                else
                    return 0;
            }
        });
    }

    public String delete() {
        try {
            categoryService.deleteById(categoryId);

            addActionMessage(getText(PROCESSED_SUCCESS));

            // if (deleteFromPage.equals("list")) {
            return list();
            // } else {
            // return input();
            // }
        } catch (Exception e) {
            addActionError(e.getMessage());
            log.error("delete exception : {}", e);
            if (deleteFromPage.equals("list")) {
                return list();
            } else {
                return input();
            }
        }

    }

    @Override
    public String input() {
        setRelated(false);
        if (StringUtils.isNotBlank(categoryId)) {
            category = categoryService.findById(categoryId);
            List<Level1Planning> list = planFirstLevelManager.findByCategoryId(categoryId);
            if (!list.isEmpty()) {
                setRelated(true);
            }
            checkHasLevel1Planning();
        }

        return INPUT;
    }

    public void getLevelStatus() {
        Category category = categoryService.findById(categoryId);
        Map<String, String> map = new HashMap<String, String>();
        if (StringUtils.isBlank(category.getBranchName())) {
            List<Planning> planningList = planningService.findByCategoryId(categoryId);
            for (Planning planning : planningList) {
                map.put(planning.getPlanningLevel().name(), planning.getStatus().getLabel());
            }
        } else {
            Level1Planning level1 = category.getLevel1Planning();
            if (level1 == null) {
                map.put(PlanningLevel.FirstLevel.name(),
                        PlanningStatus.WaitingForSubmission.getLabel());
            } else {
                map.put(PlanningLevel.FirstLevel.name(), level1.getStatus().getLabel());
            }
        }
        Struts2Utils.renderJson(map);
    }

    public void checkLevel1Endorsed() {
        Category category = categoryService.findById(categoryId);
        if (StringUtils.isBlank(category.getBranchName())) {
            Planning p = planningService.findByCategoryIdAndPlanningLevel(categoryId,
                    PlanningLevel.FirstLevel);
            if (p.getStatus().equals(PlanningStatus.Endorsed)) {
                Struts2Utils.renderText("true");
            } else {
                Struts2Utils.renderText("false");
            }
        } else {
            Level1Planning level1 = category.getLevel1Planning();
            if (level1 == null) {
                Struts2Utils.renderText("false");
            } else {
                if (level1.getStatus().equals(PlanningStatus.Endorsed)) {
                    Struts2Utils.renderText("true");
                } else {
                    Struts2Utils.renderText("false");
                }
            }
        }
    }

    // 加载category的tree
    public String loadCategoryTree() {
        return "load-category-tree";
    }

    public Category getCategory() {
        return category;
    }

    public void setCategory(final Category category) {
        this.category = category;
    }

    public boolean isSearch() {
        return search;
    }

    public void setSearch(final boolean search) {
        this.search = search;
    }

    public Page<Category> getPage() {
        return page;
    }

    public void setPage(final Page<Category> page) {
        this.page = page;
    }

    public String getXml() {
        return xml;
    }

    public void setXml(final String xml) {
        this.xml = xml;
    }

    public String getCategoryId() {
        return categoryId;
    }

    public void setCategoryId(final String categoryId) {
        this.categoryId = categoryId;
    }

    public void setCategoryService(final CategoryService categoryService) {
        this.categoryService = categoryService;
    }

    public void setCategoryNodeService(final CategoryNodeService categoryNodeService) {
        this.categoryNodeService = categoryNodeService;
    }

    public void setPageSize(final String pageSize) {
        this.pageSize = pageSize;
    }

    public CategoryNode getRoot() {
        return root;
    }

    public void setRoot(final CategoryNode root) {
        this.root = root;
    }

    public boolean isAdmin() {
        return isAdmin;
    }

    public void setAdmin(final boolean isAdmin) {
        this.isAdmin = isAdmin;
    }

    public String getLevel1PlanningId() {
        return level1PlanningId;
    }

    public void setLevel1PlanningId(final String level1PlanningId) {
        this.level1PlanningId = level1PlanningId;
    }

    public boolean isRelated() {
        return related;
    }

    public void setRelated(final boolean related) {
        this.related = related;
    }

    public CategoryService getCategoryService() {
        return categoryService;
    }

    public String getCanSelectMasterTree() {
        return canSelectMasterTree;
    }

    public void setCanSelectMasterTree(final String canSelectMasterTree) {
        this.canSelectMasterTree = canSelectMasterTree;
    }

    public String getDeleteFromPage() {
        return deleteFromPage;
    }

    public void setDeleteFromPage(final String deleteFromPage) {
        this.deleteFromPage = deleteFromPage;
    }
}
